package com.code;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@SuppressWarnings("serial")
public class CollectData implements Serializable,Cloneable {
	
	/**观测数据*/
	public static final int CODE_TESTDATA = 0x81;
	/**状态数据*/
	public static final int CODE_STATUSDATA = 0x82;
	/**参数*/
	public static final int CODE_PARAM = 0x83;
	/**成功信息*/
	public static final int CODE_SUCCESS = 0x84;
	/**错误信息*/
	public static final int CODE_ERROR = 0x85;
	/**历史数据*/
	public static final int CODE_HISTROYDATA = 0x86;
	/**取数成功*/
	public static final int CODE_SUCCESS_QUERYDATA = 0x87;
	/**选测数据*/
	public static final int CODE_SUCCESS_TEST = 0x88;
	/**状态选测数据*/
	public static final int CODE_STATUS_TESTDATA = 0x89;
	/**对象数据*/
	public static final int CODE_OBJECTDATA = 0x8A;
	
	/**心跳数据*/
	public static final int CODE_HEARTBEATDATA = 0x8B;
	
	/**信号数据*/
	public static final int CODE_SIGNALDATA = 0x12;
	
	private Long did;
    private Date rtime;
    private String ip;
    private String cardName;
    private String scode;
    private String state;
    private Integer sourceStation;
    private Integer sourceGroup;
    private Integer targetStation;
    private Integer targetGroup;
    private Integer router;
    private Integer routerGroup;
    private Integer mcode;
    private Integer tcode;
    public Integer getMcode() {
		return mcode;
	}

	public void setMcode(Integer mcode) {
		this.mcode = mcode;
	}

	public Integer getTcode() {
		return tcode;
	}

	public void setTcode(Integer tcode) {
		this.tcode = tcode;
	}

	public Integer getRouterGroup() {
		return routerGroup;
	}

	public void setRouterGroup(Integer routerGroup) {
		this.routerGroup = routerGroup;
	}

	private Integer index;
    private String data;
    private Integer dtype;
    private Integer project;
    private Integer ecode;
    private String result;
    private Date dtime;
    private boolean sended;
    private int mkh;
    public int getMkh() {
		return mkh;
	}

	public void setMkh(int mkh) {
		this.mkh = mkh;
	}

	public int getTdh() {
		return tdh;
	}

	public void setTdh(int tdh) {
		this.tdh = tdh;
	}

	private int tdh;
    private Long tid;
	public Long getDid() {
		return did;
	}
	public void setDid(Long did) {
		this.did = did;
	}
	public Date getRtime() {
		return rtime;
	}
	public void setRtime(Date rtime) {
		this.rtime = rtime;
	}
	
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getCardName() {
		return cardName;
	}
	public void setCardName(String cardName) {
		this.cardName = cardName;
	}
	public boolean from(String cardName){
		return this.cardName.equals(cardName);
	}
	public String getScode() {
		return scode;
	}
	public void setScode(String scode) {
		this.scode = scode;
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	public Integer getSourceStation() {
		return sourceStation;
	}
	public void setSourceStation(Integer sourceStation) {
		this.sourceStation = sourceStation;
	}
	public Integer getSourceGroup() {
		return sourceGroup;
	}
	public void setSourceGroup(Integer sourceGroup) {
		this.sourceGroup = sourceGroup;
	}
	public Integer getTargetStation() {
		return targetStation;
	}
	public void setTargetStation(Integer targetStation) {
		this.targetStation = targetStation;
	}
	public Integer getTargetGroup() {
		return targetGroup;
	}
	public void setTargetGroup(Integer targetGroup) {
		this.targetGroup = targetGroup;
	}
	public Integer getRouter() {
		return router;
	}
	public void setRouter(Integer router) {
		this.router = router;
	}
	public Integer getIndex() {
		return index;
	}
	public void setIndex(Integer index) {
		this.index = index;
	}
	public String getData() {
		return data;
	}
	public void setData(String data) {
		this.data = data;
	}

	public Integer getDtype() {
		return dtype;
	}
	public void setDtype(Integer dtype) {
		this.dtype = dtype;
	}
	public Integer getProject() {
		return project;
	}
	public void setProject(Integer project) {
		this.project = project;
	}
	public Integer getEcode() {
		return ecode;
	}
	public void setEcode(Integer ecode) {
		this.ecode = ecode;
	}
	public String getResult() {
		return result;
	}
	public void setResult(String result) {
		this.result = result;
	}
	public Date getDtime() {
		return dtime;
	}
	public void setDtime(Date dtime) {
		this.dtime = dtime;
	}
	
    public boolean isSended() {
		return sended;
	}
	public void setSended(boolean sended) {
		this.sended = sended;
	}

	public Long getTid() {
		return tid;
	}
	public void setTid(Long tid) {
		this.tid = tid;
	}

	private List<CollectParam> collectParams;
	public List<CollectParam> getCollectParams() {
		return collectParams;
	}
	public void setCollectParams(List<CollectParam> collectParams) {
		this.collectParams = collectParams;
	}
	public CollectParam getCollectParamByCode(int pcode){
		if (collectParams==null) return null;
		for (CollectParam collectParam:collectParams){
			if (collectParam.getPcode()==pcode) return collectParam;
		}
		return null;
	}
	public CollectParam getCollectParamByName(String pname){
		if (collectParams==null) return null;
		for (CollectParam collectParam:collectParams){
			if (pname.equals(collectParam.getPname())) return collectParam;
		}
		return null;
	}
    private static final PackageType[] packageTypes={
    	new PackageType("信号数据",0x12,false),
    	new PackageType("观测数据",0x81,false),
    	new PackageType("状态数据",0x82,false),
    	new PackageType("对象参数",0x83,false),
    	new PackageType("成功信息",0x84,false),
    	new PackageType("错误信息",0x85,false),
    	new PackageType("历史数据",0x86,false),
    	new PackageType("取数成功",0x87,false),
    	new PackageType("选测数据",0x88,false),
    	new PackageType("选测状态",0x89,false),
    	new PackageType("对象数据",0x8A,false),
    	new PackageType("心跳数据",0x8B,false),
    	new PackageType("复杂参数",0x8C,false)
    };
    public static List<PackageType> packageTypes(){
    	List<PackageType> typeList=new ArrayList<PackageType>();
    	for (PackageType packageType:packageTypes){
    		typeList.add(packageType);
    	}
    	return typeList;
    }
    public static int typeCodeOf(String typeName){
    	for (PackageType packageType:packageTypes){
    		if (packageType.getTypeName().equals(typeName)){
    			return packageType.getTypeCode();
    		}
    	}
    	return -1;
    }
    public static PackageType getPackageTypeByName(String typeName){
    	for (PackageType packageType:packageTypes){
    		if (packageType.getTypeName().equals(typeName)){
    			return packageType;
    		}
    	}
    	return null;
    }
    public static PackageType getPackageTypeByCode(int typeCode){
    	for (PackageType packageType:packageTypes){
    		if (packageType.getTypeCode()==typeCode){
    			return packageType;
    		}
    	}
    	return null;
    }
    public static boolean hasPackageTypeByCode(int typeCode){
    	for (PackageType packageType:packageTypes){
    		if (packageType.getTypeCode()==typeCode){
    			return true;
    		}
    	}
    	return false;
    }
    public String getMessage(){
    	StringBuilder message=new StringBuilder();
    	if (!"解码失败".equals(state)||"重复数据".equals(state)){
	    	
	    	message.append("[").append(getDname()).append("]").append(scode);
	    	if (0xEB96==protocal){
	    		message.append("  工程编号:").append(project).append("  对象编号:").append(ecode);
	    	}else{
	    	    message.append(" 站号:").append(sourceStation).append("  板号:").append(sourceGroup).append("  工程编号:").append(project).append("  对象编号:").append(ecode).append("  序列号:").append(index);
	    	    if (7!=protocal){
		    		int router=Integer.parseInt(getScode().substring(14, 18),16);
		    		if (router>0){
			    		message.append(" 中继站号:").append(router>>6).append(" 中继板号:").append(router&0x003F);
		    		}
		    	}
	    	}
	    	
	    	message.append(" 数据内容:[");
	    	for (CollectParam param :collectParams){
	    		if (param.getPname()==null){
	    			message.append("消息内容:").append(param.getPvalue()) ;
	    		}else if (param.getPname().equals("数字信号")){
	    			message.append("  ").append(param.getPname()).append(":").append(ByteUtil.toDataSignal(param.getPdata())).append("  ");
	    			
	    		}else{
	    			
	    			message.append("  ").append(param.getPname()).append(":").append(param.getPvalue());
	    			if (!StringUtil.isEmpty(param.getEvalue())){
	    				message.append(":").append(param.getEvalue());
	    			}
	    			if (StringUtil.isEmpty(param.getUnit())){
	    				message.append("  ");
	    			}else{
	    				message.append("(").append(param.getUnit()).append(") ");
	    			}
	    		}
	    	}
	    	if (collectParams.isEmpty()){
	    		message.append("无");
	    	}
	    	message.append("]");
	    	if (mname!=null) message.append("  ").append(mname);
	    	if (tname!=null) message.append("  ").append(tname);
	    	if (ename!=null) message.append("  ").append(ename);
	    	if ("重复数据".equals(state)){
	    		message.append(" (重复数据)");
	    	}
	    	
    	}else{
	    	message.append("[数据原码]").append(scode).append("  [").append(state).append("]  ");
	    	if (result!=null) message.append(result);
    	}
    	return message.toString();
    }
    public String getDname() {
    	if(dtype==null)return "误码数据";
    	if(getPackageTypeByCode(dtype)==null)return "未知数据";
    	if (dtype==0x85&&getCollectParams()!=null&&!getCollectParams().isEmpty()){
    		for (CollectParam cp:getCollectParams()){
        		if ("日期".equals(cp.getPname())) continue;
          		switch (cp.getPcode()){
        		case 0x01:
        		case 0x0B:return cp.getPvalue();
        		}
    			
        	}
    	}
    	
		return 	getPackageTypeByCode(dtype).getTypeName();
	}
    public String pvalue(String pname){
		if (collectParams==null) return null;
		for (CollectParam collectParam:collectParams){
			if (collectParam.pnameIs(pname)) return collectParam.getPvalue();
		}
		return null;
	}
    public boolean isType(String typeName){
		return dtype==typeCodeOf(typeName);
	}
	public boolean isType(int typeCode){
		return dtype==typeCode;
	}
	public Date rtimeOf(int gap){
		if (getCollectParams()==null||224!=getProtocal()) return getRtime();
    	for (CollectParam cp:getCollectParams()){
    		if ("日期".equals(cp.getPname())&&cp.getPvalue()!=null){
    			try {
					Date dtime=PropertyBuilder.DatetimeBuilder.parseValue(cp.getPvalue());
					if (gap==0||index>0)	return dtime;
					if (Math.abs(getRtime().getTime()-dtime.getTime())<gap) return dtime;
				} catch (Exception e) {
					e.printStackTrace();
					break;
				}
    		}
    	}
    	return getRtime();
    }
	public Date remoteTime(){
    	for (CollectParam cp:getCollectParams()){
    		if ("日期".equals(cp.getPname())&&cp.getPvalue()!=null){
    			try {
					return PropertyBuilder.DatetimeBuilder.parseValue(cp.getPvalue());
				} catch (Exception e) {
					e.printStackTrace();
					break;
				}
    		}
    	}
    	return getRtime();
    }
	public Date rtimeOf(){
    	return rtimeOf(0);
    }
	public boolean decoded(){
		return !"解码失败".equals(state)||"重复数据".equals(state);
	}
	public String error(){
		if (CODE_ERROR==dtype){
			String error="下位机返回错误信息[";
			for (CollectParam cp:getCollectParams()){
	    		if (!"日期".equals(cp.getPname())&&cp.getPvalue()!=null){
					error+=cp.getPvalue();
	    		}
	    	}
			error+="]";
			return error;
		}
		return null;
	}
	@Override
	public boolean equals(Object obj) {
		if (!CollectData.class.isInstance(obj)) return false;
		return did.equals(((CollectData)obj).did);
	}
	@Override
	public int hashCode() {
		return did==null?-1:did.hashCode();
	}
	public Integer protocal;
	
	public Integer getProtocal() {
		return protocal;
		/*if (protocal!=null) return protocal;
		if (scode.startsWith("EB90")&&scode.length()==14) return 7;
		return 224;*/
	}
	public void setProtocal(Integer protocal) {
		this.protocal = protocal;
	}

    public CollectData toNewData(){
    	CollectData newData=new CollectData();
    	newData.setRtime(rtime);
    	newData.setScode(scode);
    	newData.setCardName(cardName);
    	newData.setState("未解码");
    	newData.setIp(ip);
    	newData.setProtocal(protocal);
    	return newData;
    }
    private String mname;
	private String tname;
	private String ename;
	public String getMname() {
		return mname;
	}
	public void setMname(String mname) {
		this.mname = mname;
	}
	public String getTname() {
		return tname;
	}
	public void setTname(String tname) {
		this.tname = tname;
	}
	public String getEname() {
		return ename;
	}
	public void setEname(String ename) {
		this.ename = ename;
	}
	protected Integer pcode;
	protected String pname;
	public Integer getPcode() {
		return pcode;
	}
	public void setPcode(Integer pcode) {
		this.pcode = pcode;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public Long getHid(){
		if (getSourceGroup()<2&&getEcode()<64){
			return getProject()*100000000000l+getSourceStation()*10000000+getEcode()*100000+0xFFFE;
		}
    	return getProject()*100000000000l+getSourceStation()*10000000+getSourceGroup()*100000+getEcode();
    }
	public String getPstring(){
		if (collectParams==null||collectParams.isEmpty()) return null;
		Object[][] as=new Object[collectParams.size()][5];
		for (int i=0;i<collectParams.size();i++){
			as[i]=collectParams.get(i).array();
		}
		return JsonUtil.fromArray(as);
	}
	public void setPstring(String pstring){
		collectParams=new ArrayList<CollectParam>();
		if (!StringUtil.isEmpty(pstring)){
			Object[] as=JsonUtil.toArray(pstring);
			for (int i=0;i<as.length;i++){
				Object[] a=(Object[]) as[i];
				CollectParam cp=new CollectParam();
                cp.array(a);
                collectParams.add(cp);
			}
		}
	}
	protected String s;
	public String getS() {
		return s;
	}

	public void setS(String s) {
		this.s = s;
	}

	public boolean isState(String state) {
		return state.equals(this.state);
	}


	@Override
	protected CollectData clone() throws CloneNotSupportedException {
		CollectData clone=new CollectData();
		clone.did=did;
		clone.rtime=rtime;
		clone.cardName=cardName;
		clone.collectParams=collectParams;
		clone.data=data;
		clone.dtime=dtime;
		clone.dtype=dtype;
		clone.ecode=ecode;
		clone.index=index;
		clone.ip=ip;
		clone.mkh=mkh;
		clone.mname=mname;
		clone.pcode=pcode;
		clone.pname=pname;
		clone.project=project;
		clone.protocal=protocal;
		clone.result=result;
		clone.router=router;
		clone.routerGroup=routerGroup;
		clone.s=s;
		clone.scode=scode;
		clone.sended=sended;
		clone.sourceGroup=sourceGroup;
		clone.sourceStation=sourceStation;
		clone.state=state;
		clone.targetGroup=targetGroup;		
		clone.targetStation=targetStation;
		clone.tdh=tdh;
		clone.tid=tid;
		clone.tname=tname;
		return clone;
	}
	
}
